import ctypes 
import os
import numpy as np
FILE_PATH = os.path.realpath('')
CLIB_PATH = FILE_PATH+'/libBaseApi.so'

def Align8(x):
    if(x%8==0):
        return x 
    else: 
        return (x//8)*8+8
def Align8_(x):
    if(x%8==0):
        return x 
    else: 
        return (x//8)*8

class BaseAPI():
    def __init__(self):
        self.clib = ctypes.cdll.LoadLibrary(CLIB_PATH)
    def writeReg(self,addr,value):
        self.clib.WriteReg(addr,value)
    def devInit(self):
        self.writeReg(0x0f,0x0f)  # power
        print("power on!")
    def selectChip(self,chipNum):
        print(chipNum)
        self.writeReg(0x99,chipNum)
    def cfgReadPulse(self,ti=0x3f,ts=0x28,tb=0xff,te=0x3c):
        # ti=63, ts=40, tb=255, te=60
        regVal = (ti<<16)|(ts<<8)|tb 
        self.writeReg(6,regVal)
        self.writeReg(56,te)
    def rocc_config(self,random,wisenum,outshift,cimshift):
        self.clib.rocc_config(random,wisenum,outshift,cimshift)
    def rocc_push(self,input,start,num):
#        print(start,num)
        pushstart = Align8_(start)
        pushnum   = Align8(start+num) - pushstart
        inputptr = input.ctypes.data_as(ctypes.c_char_p)
        self.clib.rocc_push(inputptr,pushstart,pushnum)
    def rocc_save(self,start,num):
        savestart = Align8_(start)
        savenum   = Align8(start+num) - savestart
        savefront = start - savestart

#        print(start,num,savestart,savenum,savefront)

        outsave = np.zeros(savenum,dtype=np.int8)
        outsaveptr = outsave.ctypes.data_as(ctypes.c_char_p)
        self.clib.rocc_save(outsaveptr,savestart,savenum)
        return outsave[savefront:savefront+num]
    def rocc_mvm(self,array_index,mvm_row_start,mvm_row_num,mvm_col_start,mvm_col_num):
        self.clib.rocc_mvm(array_index,mvm_row_start,mvm_row_num,mvm_col_start,mvm_col_num)
